﻿using System;
using System.ComponentModel;
using System.Security.Cryptography;
using System.Text;

namespace InfiniTec.Configuration
{
    public class EncryptedStringTypeConverter: TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return sourceType == typeof(string);
        }

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return destinationType == typeof(string);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            var encryptedValue = value as string;
            if (string.IsNullOrEmpty(encryptedValue)) return encryptedValue;

            var buffer = Convert.FromBase64String(encryptedValue);
            ProtectedMemory.Unprotect(buffer, MemoryProtectionScope.CrossProcess);

            int index = 0;
            while (index < buffer.Length && buffer[index] != 0) index++;

            return Encoding.UTF8.GetString(buffer, 0, index);
        }

        public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
        {
            var clearTextValue = value as string ?? string.Empty;

            var buffer = Encoding.UTF8.GetBytes(clearTextValue);
            var difference = 16 - (buffer.Length % 16);
            if (difference == 16)
            {
                difference = 0;
            }
            Array.Resize(ref buffer, Math.Max(buffer.Length + difference, 16));
            ProtectedMemory.Protect(buffer, MemoryProtectionScope.CrossProcess);

            return Convert.ToBase64String(buffer);
        }
    }
}
